package org.club.common.util;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

/**
 * JWT过滤器，用于验证JWT令牌并设置用户认证信息
 */
public class JwtFilter extends OncePerRequestFilter {
    private static final String AUTHORIZATION_PREFIX = "Club_";

    private final JwtUtil jwtUtils;
    public JwtFilter(JwtUtil jwtUtils) {
        this.jwtUtils = jwtUtils;
    }

    /**
     * 执行过滤器的主要方法
     *
     * @param request     HTTP请求
     * @param response    HTTP响应
     * @param filterChain 过滤链
     * @throws ServletException 如果过滤过程中发生Servlet异常
     * @throws IOException      如果过滤过程中发生IO异常
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain)
            throws ServletException, IOException {
        if (request.getRequestURI().contains("/LZ/club/login")|| request.getRequestURI().contains("/LZ/club/kaptcha")|| request.getRequestURI().contains("/LZ/club/register")
        || request.getRequestURI().contains("/LZ/club/resetPassword")) {
            filterChain.doFilter(request, response);
            return;
        }
        try {
            logger.info("JwtFilter 正在处理请求");
            // 解析请求中的Token
            String token = parseToken(request);
            if (jwtUtils.validateToken(token)) {
                logger.info("JwtFilter 验证Token成功");
                // 从Token中获取用户名
                String username = jwtUtils.getUsernameFromToken(token);
                // 创建认证对象，设置用户信息
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(
                                username,
                                null,
                                new ArrayList<>()
                        );
                // 将认证对象存储到SecurityContext中
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception e) {
            logger.info(e);
            // 设置响应状态码为 401 未授权
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            // 设置响应内容类型为 JSON
            response.setContentType("application/json;charset=UTF-8");
            // 将异常信息写入响应体
            response.getWriter().write("{\"code\":401,\"message\":\"" + e.getMessage() + "\"}");
            logger.error("JwtFilter 验证Token失败", e);
            return; // 结束过滤器链
        }
        logger.info("JwtFilter 已处理请求");
        filterChain.doFilter(request, response);

    }

    /**
     * 从HTTP请求中解析Token
     *
     * @param request HTTP请求
     * @return 解析出的Token字符串，如果无法解析则返回null
     */
    private String parseToken(HttpServletRequest request) {
        String header = request.getHeader("Authorization");
        // 检查Authorization字段是否以"Club_"开头
        if (StringUtils.hasText(header) && header.startsWith(AUTHORIZATION_PREFIX)) {
            return header.substring(5);
        }
        return null;
    }
}
